##################################################################
# File : /lua/simsync.lua
# Description : Sim Side Sync
# Author : Neruz
##################################################################

# The global sync table is copied to the user layer every time the main and sim threads are
# synchronized on the sim beat (which is like a tick but happens even when the game is paused)
Sync = {}

# EntityData that has been synced. We keep a separate copy of this so when we change
# focus army we can resync the data.
EntityData = {}

function ResetSyncTable()
    Sync = {
        # A list of camera control operations that we'd like the user layer to perform.
        CameraRequests = {},
        Sounds = {},
        Voice = {},

        # Player to player queries that can affect the Sim
        PlayerQueries = {},
        QueryResults = {},

        # Contain operation data when op is complete
        OperationComplete = nil,

        EntityData = {},
        ReleaseIds = {},

        FloatText = {},

        BeginShop = {},
        EndShop = false,

        BlipMap = {},

        AIData = {
            StrategicData = {},
            SquadData = {},
            HeroData = {},
        },

        BuildUnits = {},
    }
end

function FloatTextOn(unit, text, displayType)
    # Unit Id's only work for focus army units. So you can only use FloatTextOn when
    # the unit is of the focus army.
    if (unit:GetArmy() == GetFocusArmy()) then
        table.insert(Sync.FloatText, { UnitId=unit:GetEntityId(), Text=text, Type=displayType })
    end
end

function FloatTextAt(pos, text, displayType, viztoarmy)
    #LOG("*DEBUG: VizToArmy: ", repr(viztoarmy), " FocusArmy: ", repr(GetFocusArmy()))
    if viztoarmy and viztoarmy != GetFocusArmy() then
        return
    end
    local detect = ArmyCanDetect(GetFocusArmy(),pos,"LOSNow")
    if detect.LOSNow then
        table.insert(Sync.FloatText, { Position=pos, Text=text, Type=displayType })
    end
end

# Shows floattext through the shroud
function FloatTextAllAt(pos, text, displayType)
    table.insert(Sync.FloatText, { Position = pos, Text = text, Type = displayType })
end

function SyncPlayableRect(rect)
    local Camera = import('/lua/sim/SimCamera.lua').SimCamera
    local cam = Camera("WorldCamera")
    cam:SyncPlayableRect(rect)
end

#Announcement 'loc' is 1 for top, 2 for middle, 3 for bottom
function Announce(smallText, splashText, army, loc, audio)
    if not army or (army and army == GetFocusArmy()) then
        if not Sync.Announcement then
            Sync.Announcement = { SmallText = smallText, SplashText = splashText, Location = loc, Audio = audio}
            #LOG("*DEBUG: Announcing: ", repr(Sync.Announcement))
        else
            #LOG("*DEBUG: Queuing Announcement: "..smallText.. " "..splashText)
            ForkThread(QueueAnnouncementThread, smallText, splashText, army, loc, audio)
        end

    end
end

function QueueAnnouncementThread(smallText, splashText, army, loc, audio)
    WaitTicks(1)
    Announce(smallText, splashText, army, loc, audio)
end

function LockInput()
    Sync.LockInput = true
end

function UnlockInput()
    Sync.UnlockInput = true
end